package com.yheriatovych.reductor.example.reductor.utils;

import com.yheriatovych.reductor.Action;
import com.yheriatovych.reductor.Reducer;
import com.yheriatovych.reductor.Store;

import java.util.LinkedList;

/**
 * Reducer which add 'Undo' action to existing reducer.
 *
 * @param <State>
 * @since 2021-05-06
 */
public class UndoableReducer<State> implements Reducer<State> {
    private final Reducer<State> sourceReducer;

    private LinkedList<State> stack = new LinkedList<>();

    /**
     * 构造方法
     *
     * @param sourceReducer
     */
    public UndoableReducer(Reducer<State> sourceReducer) {

        this.sourceReducer = sourceReducer;
    }

    /**
     * 弹出
     *
     * @return Action
     */
    public static Action pop() {
        return Action.create("POP");
    }

    @Override
    public State reduce(State state, Action action) {
        if (action.type.equals("POP")) {
            return stack.isEmpty()
                    ? state
                    : stack.pop();
        } else if (!action.type.equals(Store.INIT_ACTION)) {
            stack.push(state);
        }
        return sourceReducer.reduce(state, action);
    }
}
